package com.atguigu.spzx.cart.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.atguigu.spzx.cart.service.CartService;
import com.atguigu.spzx.common.exception.XiaoHeiException;
import com.atguigu.spzx.feign.product.ProductFeignClient;
import com.atguigu.spzx.model.entity.h5.CartInfo;
import com.atguigu.spzx.model.entity.product.Product;
import com.atguigu.spzx.model.entity.product.ProductSku;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.utils.AuthContextUtil;
import jakarta.annotation.Resource;
import org.checkerframework.checker.units.qual.A;
import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ClassName: CartServiceImpl
 * Package:
 * Description:
 *
 * @Author:xiaohei
 * @Create 2024/5/23 9:45
 * Version 1.0
 */
@Service
public class CartServiceImpl implements CartService {

    @Resource
    private RedisTemplate<String,String> redisTemplate;
    @Resource
    private ProductFeignClient productFeignClient;

    //用来生成key的工具方法
    private String getCartKey(Long userId) {
        //定义key user:cart:userId
        return "user:cart:" + userId;
    }

    //添加购物车
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //1 必须登录状态  获取当前用户id（作为redis中hash类型中的key
        //从Thread中获取用户信息
        Long userId = AuthContextUtil.getUserInfo().getId();
        //构建hash类型中key的名称
        String cartKey = getCartKey(userId);

        //2 因为购物车是redis中存储
        //hash类型  KEY：用户id   field：skuid  value：信息CartInfo
        //从redis里获取购物车数据，根据用户id+skuId获取（hash类型的key+field）
        Object cartInfoObj = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId));

        //3  如果购物车里面已经存在要添加的商品，把商品数量相加
        CartInfo cartInfo = null;
        if(cartInfoObj != null){
//            cartInfoObj -> cartInfo
            cartInfo = JSON.parseObject(cartInfoObj.toString(), CartInfo.class);
            //数量想加
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            //设置属性  表示添加到购物车的商品默认选中
            cartInfo.setIsChecked(1);
            cartInfo.setUpdateTime(new Date());
        }else{
            //4  如果购物车没有要添加的商品  则直接添加
            //远程调用实现：通过nacos+openFeign实现  根据商品skuId获取商品信息
            cartInfo = new CartInfo();

            //远程调用实现  根据skuId获取到sku的信息
            ProductSku productSku = productFeignClient.getBySkuId(skuId);
            //设置相关数据到cartInfo对象中
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setSkuId(skuId);
            cartInfo.setUserId(userId);
            cartInfo.setImgUrl(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setIsChecked(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());

        }
        //添加到redis中去
        redisTemplate.opsForHash().put(cartKey,
                String.valueOf(skuId),
                JSON.toJSONString(cartInfo));

    }

    //查询购物车
    @Override
    public List<CartInfo> getCartList() {
        //1 构建查询的redis里面key的值  根据当前userId
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = this.getCartKey(userId);

        //2 根据key从redis里面hash类型获取所有value值cartInfo
        List<Object> valueList = redisTemplate.opsForHash().values(cartKey);

        //List<Object> -》List<CartInfo>
        if(CollectionUtils.isEmpty(valueList)){
            List<CartInfo> cartInfoList = valueList.stream().map(cartInfoObj ->
                    JSON.parseObject(cartInfoObj.toString(), CartInfo.class))
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
            return cartInfoList;
        }

        //构建成一个list集合返回
        return new ArrayList<>();
    }

    //删除购物车商品
    @Override
    public void deleteCart(Long skuId) {
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = this.getCartKey(userId);

        redisTemplate.opsForHash().delete(cartKey,String.valueOf(skuId));
    }

    //更新购物车中商品的选中状态
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //1 根据用户id构建redis中key的值
        String cartKey = this.getCartKey(AuthContextUtil.getUserInfo().getId());

        //2 判断key是否包含field
        Boolean hasKey = redisTemplate.opsForHash().hasKey(cartKey, String.valueOf(skuId));

        if(hasKey){
            //3 根据key + field把value获取出来
            String cartInfoString = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId)).toString();

            //4 更新value里面选中状态
            CartInfo cartInfo = JSON.parseObject(cartInfoString, CartInfo.class);
            cartInfo.setIsChecked(isChecked);

            //5 放回到redis的hash类型里面
            redisTemplate.opsForHash().put(cartKey,String.valueOf(skuId),JSON.toJSONString(cartInfo));
        }

    }

    //购物车的全选功能
    @Override
    public void allCheckCart(Integer isChecked) {
        //1 根据用户id构建redis中key的值
        String cartKey = this.getCartKey(AuthContextUtil.getUserInfo().getId());

        //2 根据key获取全部的商品value
        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);

        if(!CollectionUtils.isEmpty(objectList)){
            List<CartInfo> cartInfoList = objectList.stream().map(item ->
                    JSON.parseObject(item.toString(), CartInfo.class)).collect(Collectors.toList());

            //3 遍历得到每个cartinfo  更新isChecked
            cartInfoList.forEach(cartInfo -> {
                cartInfo.setIsChecked(isChecked);
                //3 把每个商品的isChecked值进行更新
                redisTemplate.opsForHash().put(cartKey, String.valueOf(cartInfo.getSkuId()),JSON.toJSONString(cartInfo));
            });
        }
    }

    @Override
    public void clearCart() {
        String cartKey = this.getCartKey(AuthContextUtil.getUserInfo().getId());

        redisTemplate.opsForHash().delete(cartKey);
    }

    @Override
    public List<CartInfo> getAllCkecked() {
        //获取userId  构建key
        String cartKey = this.getCartKey(AuthContextUtil.getUserInfo().getId());

        //根据key获取所有购物车商品
        List<Object> valuesList = redisTemplate.opsForHash().values(cartKey);

        if(CollectionUtils.isEmpty(valuesList)){
            List<CartInfo> cartInfoList = valuesList.stream().map(cartInfo ->
                            JSON.parseObject(cartInfo.toString(), CartInfo.class))
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .collect(Collectors.toList());
            return cartInfoList;
        }
        return new ArrayList<>();
    }

    @Override
    public void deleteChecked() {
        String cartKey = this.getCartKey(AuthContextUtil.getUserInfo().getId());

        //根据key获取redis所有value值
        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);

        if(CollectionUtils.isEmpty(objectList)){
            throw  new XiaoHeiException(ResultCodeEnum.DATA_ERROR);
        }
        //删除选中的商品
        objectList.stream().map(object -> JSON.parseObject(object.toString(),CartInfo.class))
                .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                .forEach(cartInfo -> redisTemplate.opsForHash().delete(cartKey,String.valueOf(cartInfo.getSkuId())));
    }

}
